/////////////////////////////////////////////////////////////////////////////////////
// vertex programs

struct vert_out
{
	float4 vPosition  : POSITION;
	float3 vTexCoord0 : TEXCOORD0;
};

vert_out vertex( float4 _vPosition : ATTR0, uniform float4x4 _matModelViewProj )
{
	vert_out ret;

	ret.vPosition  = mul( _vPosition, _matModelViewProj );
	ret.vTexCoord0 = _vPosition.xyz;

	return ret;
}

/////////////////////////////////////////////////////////////////////////////////////
// fragment programs

struct frag_out
{
	float4 vColor : COLOR;
};

frag_out fragment( float3 _vTexCoord0 : TEXCOORD0, uniform samplerCUBE _Tex )
{
	frag_out ret;

	// normalize the texture coordinates
	_vTexCoord0 = normalize(_vTexCoord0);

	// find the fragment color
	ret.vColor = texCUBE(_Tex, _vTexCoord0);

	// find fog amount
	float fFog;
	if( _vTexCoord0.y < 0.0 )
	{
		fFog = 1.0;
	}
	else
	{
		fFog = sqrt(1.0 - _vTexCoord0.y);
	}

	// apply fog
	ret.vColor = lerp(ret.vColor, float4(0.63, 0.76, 0.94, 1.00), fFog);

	return ret;
}

/////////////////////////////////////////////////////////////////////////////////////
// techniques

float4x4 g_matModelViewProj;

samplerCUBE SkySampler = sampler_state
{
	WrapS = ClampToEdge;
	WrapT = ClampToEdge;
};

technique sky_tech_nvidia
{
	pass sky_tech_nvidia_pass0
	{
		CullFaceEnable = true;

		VertexProgram   = compile gp5vp vertex(g_matModelViewProj);
		FragmentProgram = compile gp5fp fragment(SkySampler);
	}
}

technique sky_tech_amd
{
	pass sky_tech_amd_pass0
	{
		CullFaceEnable = true;

		VertexProgram   = compile arbvp1 vertex(g_matModelViewProj);
		FragmentProgram = compile arbfp1 fragment(SkySampler);
	}
}
